package com.blog4java.mybatis.example;

import com.alibaba.fastjson.JSON;
import com.blog4java.common.DbUtils;
import com.blog4java.mybatis.example.entity.UserEntity;
import com.blog4java.mybatis.example.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

public class MybatisCacheExample {

    @Before
    public void initData() {
        DbUtils.initData();
    }

    @Test
    public void testMybatisCache() throws IOException {
        // 获取配置文件输入流
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        // 通过SqlSessionFactoryBuilder的build()方法创建SqlSessionFactory实例
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 调用openSession()方法创建SqlSession实例
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
        	//获取UserMapper代理对象
        	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        	//执行Mapper方法，获取执行结果
        	List<UserEntity> userList = userMapper.listAllUser();        	
        	System.out.println(JSON.toJSONString(userList));       	        	
        	sqlSession.commit();
        }finally {
            sqlSession.close();
        }                
        sqlSession = sqlSessionFactory.openSession();
        try {
        	//再次查询,会从缓存中获取
        	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        	List<UserEntity> userList = userMapper.listAllUser();        	
        	System.out.println(JSON.toJSONString(userList));
        	//执行更新语句,对于insert、update、delete来说flushCache默认为true,会导致本地缓存和二级缓存被清空
        	UserEntity userEntity = new UserEntity();
        	userEntity.setName("李四");        	
        	userEntity.setPassword("123456");
        	userEntity.setPhone("18527692478");
        	userEntity.setNickName("小李子");
        	userMapper.insertUser(userEntity);
        	//再次查询,重新从数据库获取并放入缓存
        	userList = userMapper.listAllUser(); 
        	System.out.println(JSON.toJSONString(userList));
        	sqlSession.commit();
        }finally {
            sqlSession.close();
        }
    }
    
    @Test
    public void testMybatisRedisCache() throws IOException {
        // 获取配置文件输入流
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        // 通过SqlSessionFactoryBuilder的build()方法创建SqlSessionFactory实例
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 调用openSession()方法创建SqlSession实例
        SqlSession sqlSession = sqlSessionFactory.openSession();
        /**
         * 1.实体类必须实现Serializable接口
         * 2.事务提交后才会写入Redis缓存
         * 3.可通过redis.properties配置不同命名空间的缓存策略
         * 4.测试时需观察Redis键命名规则（如"com.example.UserMapper"前缀）
         */
        try {
        	// 获取UserMapper代理对象
        	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);       
        	// 执行Mapper方法，获取执行结果
        	List<UserEntity> userList = userMapper.listAllUser();
        	System.out.println(JSON.toJSONString(userList));    
        	sqlSession.commit();
        }finally {
            sqlSession.close();
        }
        sqlSession = sqlSessionFactory.openSession();
        try {
        	//再次查询,会从缓存中获取
        	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        	List<UserEntity> userList = userMapper.listAllUser();        	
        	System.out.println(JSON.toJSONString(userList));
        	//执行更新语句,对于insert、update、delete来说flushCache默认为true,会导致本地缓存和二级缓存被清空
        	UserEntity userEntity = new UserEntity();
        	userEntity.setName("李四");
        	userEntity.setPassword("123456");
        	userEntity.setPhone("18527692478");
        	userEntity.setNickName("小李子");
        	userMapper.insertUser(userEntity);
        	//再次查询,重新从数据库获取并放入缓存
        	userList = userMapper.listAllUser(); 
        	System.out.println(JSON.toJSONString(userList));
        	sqlSession.commit();
        }finally {
            sqlSession.close();
        }        
    }
}
